//
// Created by yyancy on 2020/4/18.
//

#ifndef CPP_EXERCISES_QUEUE_H
#define CPP_EXERCISES_QUEUE_H

class Customer {
private:
    long arrive; //arrival time for customer
    int processtime; // processing time for customer
public:
    Customer() { arrive = processtime = 0; }

    void set(long when);

    long when() const { return arrive; }

    int ptime() const { return processtime; }
};


typedef Customer Item;

template<typename Type>
class Queue {
private:
    struct Node {
        Type item;
        struct Node *next;
    };
    enum {
        Q_SIZE = 10
    };

    Node *front;
    Node *rear;
    int items;
    const int qsize;


public:
    Queue(const Queue &q) = delete;

    Queue &operator=(const Queue &q) = delete;

    explicit Queue(int qs = Q_SIZE);

    ~Queue();

    bool isempty() const;

    bool isfull() const;

    int queuecount() const;

    bool enqueue(const Type &item);

    bool dequeue(Type &item);
};


template<typename Type>
Queue<Type>::Queue(int qs) : qsize(qs) {
    front = rear = nullptr;
    items = 0;
}

template<typename Type>
Queue<Type>::~Queue() {
    Node *temp;
    while (front != nullptr) {
        temp = front;
        front = front->next;
        delete temp;
    }
}

template<typename Type>
bool Queue<Type>::isempty() const {
    return items == 0;
}

template<typename Type>
bool Queue<Type>::isfull() const {
    return items >= qsize;
}

template<typename Type>
int Queue<Type>::queuecount() const { return items; }


template<typename Type>
bool Queue<Type>::dequeue(Type &item) {
    if (front == nullptr)
        return false;

    item = front->item;
    items--;
    Node *temp = front;
    front = front->next;
    delete temp;
    if (items == 0)
        rear = nullptr;

    return true;

}

template<typename Type>
bool Queue<Type>::enqueue(const Type &item) {
    if (isfull())return false;

    Node *add = new Node;
    add->item = item;
    add->next = nullptr;
    items++;

    if (front == nullptr)
        front = add;
    else
        rear->next = add;

    rear = add;
    return true;

}


#endif //CPP_EXERCISES_QUEUE_H
